"use client";

import { useEffect, useRef, useCallback, useState } from "react";
import { useSession } from "next-auth/react";
import { useParams, redirect, useRouter } from "next/navigation";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Loader2, Video, AlertTriangle, FileText, Clock, XCircle } from "lucide-react";
import { ConsultationNotes } from "@/components/appointments/ConsultationNotes";
import RecordsModal from "@/components/records/RecordsModal";
import type { Record as MedicalRecord } from "@/components/records/types";
import type { Appointment } from "@/types/appointments";
import { canJoinMeeting, getAppointmentTimeStatus } from "@/utils/appointments";

interface JitsiMeetExternalAPI {
  dispose: () => void;
  addEventListener: (event: string, handler: () => void) => void;
}

declare global {
  interface Window {
    JitsiMeetExternalAPI: new (domain: string, options: Record<string, unknown>) => JitsiMeetExternalAPI;
  }
}

export default function MeetPage() {
  const router = useRouter();
  const { data: session, status } = useSession();
  const params = useParams();
  const jitsiContainer = useRef<HTMLDivElement>(null);
  const jitsiApi = useRef<JitsiMeetExternalAPI | null>(null);
  const isInitialized = useRef(false);
  const isLeavingIntentionally = useRef(false);
  const [showExitDialog, setShowExitDialog] = useState(false);
  const [showRecordsModal, setShowRecordsModal] = useState(false);
  const [appointment, setAppointment] = useState<Appointment | null>(null);
  const [loading, setLoading] = useState(true);
  const [accessDenied, setAccessDenied] = useState(false);
  const [denialReason, setDenialReason] = useState("");
  const [jitsiToken, setJitsiToken] = useState<string | null>(null);
  const [jitsiDomain, setJitsiDomain] = useState<string>("");
  const [jitsiRoomName, setJitsiRoomName] = useState<string>("");
  const [useJWT, setUseJWT] = useState<boolean>(false);

  // Cargar información del appointment y JWT token
  useEffect(() => {
    const loadAppointment = async () => {
      try {
        const response = await fetch(`/api/appointments/${params.id}`);
        if (response.ok) {
          const data = await response.json();
          setAppointment(data);

          // Validar acceso por tiempo
          const timeCheck = canJoinMeeting(data.fechaSolicitada);
          if (!timeCheck.canJoin) {
            setAccessDenied(true);
            setDenialReason(timeCheck.reason || "No puedes acceder a esta videollamada");
            setLoading(false);
            return;
          }

          // Validar que la cita esté aprobada
          if (data.estado !== "APROBADA" && data.estado !== "COMPLETADA") {
            setAccessDenied(true);
            setDenialReason("Esta cita no está aprobada");
            setLoading(false);
            return;
          }

          // Obtener JWT token para Jitsi
          const tokenResponse = await fetch(`/api/appointments/${params.id}/jitsi-token`);
          if (tokenResponse.ok) {
            const tokenData = await tokenResponse.json();
            setJitsiToken(tokenData.token || null);
            setJitsiDomain(tokenData.domain || "");
            setJitsiRoomName(tokenData.roomName || `appointment-${params.id}`);
            setUseJWT(tokenData.useJWT || false);
          } else {
            console.warn("No se pudo obtener JWT token, usando configuración por defecto");
            setJitsiRoomName(`appointment-${params.id}`);
            // Si falla, intentar obtener el dominio del response aunque sea error
            const errorData = await tokenResponse.json().catch(() => ({}));
            if (errorData.domain) {
              setJitsiDomain(errorData.domain);
            }
          }
        } else {
          setAccessDenied(true);
          setDenialReason("No se pudo cargar la información de la cita");
        }
      } catch (error) {
        console.error("Error loading appointment:", error);
        setAccessDenied(true);
        setDenialReason("Error al cargar la cita");
      } finally {
        setLoading(false);
      }
    };

    if (params.id) {
      loadAppointment();
    }
  }, [params.id]);

  const handleCopyContent = (content: string) => {
    navigator.clipboard.writeText(content);
    // TODO: Add notification
  };

  const handleDownloadReport = (record: MedicalRecord) => {
    const blob = new Blob([record.content], { type: "text/plain" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `reporte-medico-${record.id.slice(-8)}-${new Date().toISOString().split("T")[0]}.txt`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    // TODO: Add notification
  };

  const handleGeneratePDF = async (_record: MedicalRecord) => {
    // TODO: Implement PDF generation
  };

  const initJitsi = useCallback(() => {
    if (!jitsiContainer.current || !session || isInitialized.current || !jitsiRoomName) return;

    isInitialized.current = true;

    const options: Record<string, unknown> = {
      roomName: jitsiRoomName,
      width: "100%",
      height: 600,
      parentNode: jitsiContainer.current,
      configOverwrite: {
        startWithAudioMuted: false,
        startWithVideoMuted: false,
        prejoinPageEnabled: false,
      },
      interfaceConfigOverwrite: {
        TOOLBAR_BUTTONS: [
          "microphone",
          "camera",
          "closedcaptions",
          "desktop",
          "fullscreen",
          "fodeviceselection",
          "hangup",
          "chat",
          "settings",
          "videoquality",
          "filmstrip",
          "tileview",
        ],
        SHOW_JITSI_WATERMARK: false,
        SHOW_WATERMARK_FOR_GUESTS: false,
      },
      userInfo: {
        displayName: `${session.user?.name || "Usuario"} ${session.user?.lastname || ""}`.trim(),
        email: session.user?.email || undefined,
      },
    };

    // Si se usa JWT, agregar el token
    if (useJWT && jitsiToken) {
      options.jwt = jitsiToken;
    }

    jitsiApi.current = new window.JitsiMeetExternalAPI(jitsiDomain, options);

    // Event listeners - Solo redirigir si el usuario salió desde Jitsi directamente
    jitsiApi.current.addEventListener("videoConferenceLeft", () => {
      // Dar un pequeño delay para que el beforeunload se procese
      setTimeout(() => {
        if (isLeavingIntentionally.current) {
          router.push("/appointments");
        }
      }, 100);
    });

    jitsiApi.current.addEventListener("readyToClose", () => {
      setTimeout(() => {
        if (isLeavingIntentionally.current) {
          router.push("/appointments");
        }
      }, 100);
    });
  }, [session, jitsiRoomName, jitsiDomain, jitsiToken, useJWT, router]);

  const handleExitClick = () => {
    setShowExitDialog(true);
  };

  const handleConfirmExit = () => {
    isLeavingIntentionally.current = true;
    if (jitsiApi.current) {
      jitsiApi.current.dispose();
      jitsiApi.current = null;
    }
    isInitialized.current = false;
    router.push("/appointments");
  };

  const handleCancelExit = () => {
    setShowExitDialog(false);
  };

  // Interceptar cierre de pestaña o navegación
  useEffect(() => {
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      // Solo mostrar advertencia si NO es una salida intencional
      if (!isLeavingIntentionally.current) {
        e.preventDefault();
        e.returnValue = "¿Estás seguro de que quieres salir de la videollamada?";
        return e.returnValue;
      }
    };

    window.addEventListener("beforeunload", handleBeforeUnload);

    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
    };
  }, []);

  useEffect(() => {
    if (status === "loading" || !session || !jitsiContainer.current || isInitialized.current || !jitsiDomain || !jitsiRoomName) return;

    // Construir la URL del script usando el dominio configurado
    const scriptSrc = `https://${jitsiDomain}/external_api.js`;

    // Verificar si el script ya está cargado
    const existingScript = document.querySelector(`script[src="${scriptSrc}"]`);

    if (existingScript) {
      // Si el script ya existe y window.JitsiMeetExternalAPI está disponible, inicializar directamente
      if (window.JitsiMeetExternalAPI) {
        initJitsi();
      }
      return;
    }

    // Cargar Jitsi script desde el dominio configurado
    const script = document.createElement("script");
    script.src = scriptSrc;
    script.async = true;
    script.onload = () => initJitsi();
    script.onerror = () => {
      console.error(`Error al cargar el script de Jitsi desde ${scriptSrc}`);
      setAccessDenied(true);
      setDenialReason("No se pudo conectar con el servidor de videollamadas");
    };
    document.body.appendChild(script);

    return () => {
      if (jitsiApi.current) {
        jitsiApi.current.dispose();
        jitsiApi.current = null;
      }
      isInitialized.current = false;
      // No eliminar el script aquí para evitar conflictos
    };
  }, [status, session, jitsiDomain, jitsiRoomName, initJitsi]);

  if (status === "loading" || loading) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <Loader2 className="h-8 w-8 animate-spin" />
      </div>
    );
  }

  if (!session) {
    redirect("/auth/login");
  }

  // Mostrar pantalla de acceso denegado si no cumple las condiciones
  if (accessDenied) {
    return (
      <div className="container mx-auto px-4 py-8 max-w-2xl">
        <Card>
          <CardHeader>
            <div className="flex items-center gap-2 text-destructive">
              <XCircle className="h-6 w-6" />
              <CardTitle>Acceso no permitido</CardTitle>
            </div>
          </CardHeader>
          <CardContent className="space-y-4">
            <p className="text-muted-foreground">{denialReason}</p>
            
            {appointment?.fechaSolicitada && (
              <div className="bg-muted p-4 rounded-lg">
                <div className="flex items-center gap-2 mb-2">
                  <Clock className="h-5 w-5" />
                  <p className="font-medium">Estado de la cita</p>
                </div>
                <p className="text-sm text-muted-foreground">
                  {getAppointmentTimeStatus(appointment.fechaSolicitada)}
                </p>
              </div>
            )}
            
            <div className="flex gap-2">
              <Button onClick={() => router.push(`/appointments/${params.id}`)}>
                Ver detalles de la cita
              </Button>
              <Button variant="outline" onClick={() => router.push("/appointments")}>
                Volver a mis citas
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>
    );
  }

  const isDoctor = session.user.role === "DOCTOR";
  const appointmentId = params.id as string;

  return (
    <>
      <div className="container mx-auto px-4 py-8 max-w-7xl">
        <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
          {/* Videollamada - 2 columnas en pantallas grandes */}
          <div className="lg:col-span-2">
            <Card>
              <CardHeader>
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <Video className="h-6 w-6" />
                    <CardTitle>Consulta Telemática</CardTitle>
                  </div>
                  <div className="flex items-center gap-2">
                    {appointment?.record && (
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => setShowRecordsModal(true)}
                      >
                        <FileText className="h-4 w-4 mr-2" />
                        Ver Reporte
                      </Button>
                    )}
                    <Button variant="outline" onClick={handleExitClick}>
                      Salir
                    </Button>
                  </div>
                </div>
              </CardHeader>
            <CardContent>
              <div ref={jitsiContainer} className="w-full rounded-lg overflow-hidden bg-muted" />
            </CardContent>
          </Card>
        </div>

        {/* Notas de consulta - 1 columna en pantallas grandes */}
        <div className="lg:col-span-1">
          <ConsultationNotes appointmentId={appointmentId} isDoctor={isDoctor} />
        </div>
      </div>
    </div>

    {/* Records Modal */}
    <RecordsModal
      isOpen={showRecordsModal}
      record={appointment?.record as MedicalRecord || null}
      generatingPDF={false}
      onClose={() => setShowRecordsModal(false)}
      onCopyContent={handleCopyContent}
      onDownloadReport={handleDownloadReport}
      onGeneratePDF={handleGeneratePDF}
    />

    {/* Modal de confirmación de salida */}
    <Dialog open={showExitDialog} onOpenChange={setShowExitDialog}>
      <DialogContent>
        <DialogHeader>
          <div className="flex items-center gap-2">
            <AlertTriangle className="h-5 w-5 text-destructive" />
            <DialogTitle>¿Salir de la videollamada?</DialogTitle>
          </div>
          <DialogDescription>
            Si sales ahora, la videollamada se cerrará. {isDoctor && "Asegúrate de haber guardado las notas de consulta si las tienes."}
          </DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <Button variant="outline" onClick={handleCancelExit}>
            Cancelar
          </Button>
          <Button variant="destructive" onClick={handleConfirmExit}>
            Salir de la llamada
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  </>
  );
}
